local json = sjson

--- because the server of activity do only server the abstract business not the specify acitivity
--- so the tool or the connection to the server is not specify ,then put them on this file
local http = {}

local HTTP_USR_TIMOEUT = 5      --nsdk defult http-timeout (s)
local HTTP_MAX_TRYTIMES= 3      --retry threshold

local HTTP_ERROR_STATUS = {
    400,    --Invalid request
    401,    --Authentication is required to access this resource
    403,    --Forbidden
    404,    --Specified resource could not be found
    407,    --Proxy authentication failed
    -- 408, --Request timed out
    412,    --Request aborted
    500     --Internal server error
}

--- Describe what http_post does (post http request).
-- @param url
-- @param param_table the table we post
-- @param cb the callback function when request response
-- @param header the table of header-params
-- @return nil
local function http_post(url,param_table,cb,exparm)
    exparm = exparm or {}

    local retry = exparm["retry"] or HTTP_MAX_TRYTIMES
    local _failidx = 0  --now filetime idx
    local _failcb
    local _execute

    function _execute()
        local header  = exparm["header"] or {}
        local resp
        http.post(url, header, json.encode(param_table), function(code, data)
            if code > 0 then 
                xpcal(function() data = json.decode(data) end, function() end)
                if resp then 
                    if type(cb) == "function" then 
                        cb(true, resp)
                    end
                else 
                    cb(false, resp)
                end
            else 
                if retry then 
                    _failcb()
                else 
                    cb(false)
                end
            end
        end)
        nsdk.Logger:info("NSDK HTTP-GET ---->>url %s", url)
    end

    function _failcb(xhr)
        _failidx  = _failidx + 1
        if _failidx > retry then
            cb(false)
            -- nsdk.Logger:warning("NSDK HTTP-GET raise timeout-->%s", url)
            -- local ENUMLOG = require("xl.framework.cfg.enumlog")
            -- nsdk.clidevMgr:postClientDot(ENUMLOG.dotstep.client_http_timeout, url)
        else
            -- nsdk.Logger:info("NSDK HTTP-GET retry idx-->%d|url-->%s", _failidx, url)
            _execute()
        end
    end
    _execute()

end
http.post = http_post

--- Describe what http_get does (get http request).
-- @param url
-- @param cb the callback function when request response
-- @param exparm the http extra parms  **kwargs{reptype=$string, retry=$boolean, header=$dic}
-- @return nil
local function http_get(url,cb,exparm)
    exparm = exparm or {}

    local retry = exparm["retry"] or HTTP_MAX_TRYTIMES
    local _failidx = 0  --now filetime idx
    local _failcb
    local _execute

    function _execute()
        local header  = exparm["header"] or {}
        local resp
        http.get(url, header, function(code, data)
            if code > 0 then 
                xpcal(function() data = json.decode(data) end, function() end)
                if resp then 
                    if type(cb) == "function" then 
                        cb(true, resp)
                    end
                else 
                    cb(false, resp)
                end
            else 
                if retry then 
                    _failcb()
                else 
                    cb(false)
                end
            end
        end)
        nsdk.Logger:info("NSDK HTTP-GET ---->>url %s", url)
    end

    function _failcb(xhr)
        _failidx  = _failidx + 1
        if _failidx > retry then
            cb(false)
            -- nsdk.Logger:warning("NSDK HTTP-GET raise timeout-->%s", url)
            -- local ENUMLOG = require("xl.framework.cfg.enumlog")
            -- nsdk.clidevMgr:postClientDot(ENUMLOG.dotstep.client_http_timeout, url)
        else
            -- nsdk.Logger:info("NSDK HTTP-GET retry idx-->%d|url-->%s", _failidx, url)
            _execute()
        end
    end
    _execute()

end
http.get = http_get

--- get url的拼接   
-- @tparam string baseurl
-- @tparam string actname
-- @tparam table parmdic
-- @return 拼接好的带参数的url
local function crtUrlWithParms(baseurl, actname, parmdic)
    local ret = ""
    local tmp = ""
    local index = 0
    local keys = table.keys(parmdic)
    local ret2 = ""
    table.sort( keys )
    for _, key in ipairs(keys) do
        ret = ret .. key .. "=" .. parmdic[key].. "&"
        index = index + 1
    end
    local url_parm = string.sub(ret, 1, string.len(ret) - 1)
    local ret =  index > 0 and baseurl..actname.."?"..url_parm or baseurl..actname
    return ret
end
http.crtUrlWithParms = crtUrlWithParms


local function form_upload_file(url, tarf, timeout, cb, failcb)
    timeout = timeout or 10
    local function http_upload(sendbody, exparm)
        exparm = exparm or {}
        local xhr = cc.XMLHttpRequest:new()
        xhr:open("POST", url)
        xhr.timeout = timeout
        local header  = exparm["header"] or {}
        for k, v in pairs( header ) do
            xhr:setRequestHeader(k, v)
        end
        xhr:registerScriptHandler(function()
            local resp, respraw = nil, xhr.responseText
            if xhr.readyState == 4 and (xhr.status >= 200 and xhr.status < 207) then
                if type(cb) == "function" then 
                    cb()
                end
            else 
                if type(failcb) == "function" then 
                    failcb()
                end
            end
        end)
        xhr:send(sendbody)
    end
    local body = {}
    local BOUNDARY = "------------ddddddddd"
    local LING_END = "\r\n"

    local fp = io.open(tarf, "rb")
    local data = fp:read()
    fp:close()
    table.insert(body, string.format("--%s", BOUNDARY))
    table.insert(body, string.format([[Content-Disposition: form-data; name="%s"; filename="%s"]] ,"logtxt", "test_cli.log"))
    table.insert(body, string.format([[Content-Type: 'text/plain'%s]], LING_END))
    table.insert(body, data)
    table.insert(body, string.format('--%s--\r\n', BOUNDARY))
    local ret = table.concat(body, LING_END)
    http_upload(ret,{
        header = {
            ['Content-Type'] =  string.format([[multipart/form-data; boundary=%s ]], BOUNDARY),
        } 
    })
end
http.form_update_file = form_upload_file


return http
